package com.acme.bankapp.domain.email;

import java.util.ArrayList;
import java.util.List;

import com.acme.bankapp.domain.exceptions.QueueClosedException;

public class Queue<T> {
	private Object mutex = new Object();
	private List<T> list = new ArrayList<T>();
	private int maxSize = 10;
	private volatile boolean isClosed;
	
	public Queue(int maxSize) {
		this.maxSize = maxSize;
	}

	public void addItem(T item) throws InterruptedException, QueueClosedException {
		synchronized (mutex) {
			while (list.size() >= maxSize) {
				if (isClosed())
					throw new QueueClosedException();
				mutex.wait();
			}
			if (isClosed())
				throw new QueueClosedException();
			list.add(item);
			mutex.notifyAll();
		}
	}
	
	public T getItem() throws InterruptedException {
		synchronized (mutex) {
			while (list.isEmpty()) {
				wait();
			}
			mutex.notifyAll();
			return list.remove(0);
		}
	}
	
	public void close() {
		synchronized (mutex) {
			setClosed(true);
			mutex.notifyAll();
		}
	}
	
	public synchronized void open() {
		setClosed(false);
		notifyAll();
	}
	
	public boolean isClosed() {
		return isClosed;
	}

	private void setClosed(boolean closed) {
		this.isClosed = closed;
	}
	
	public void setMaxSize(int maxSize) {
		synchronized (mutex) {
			this.maxSize = maxSize;
			mutex.notifyAll();
		}
	}
	
	public int getSize() {
		synchronized (mutex) {
			return list.size();
		}
	}
}
